<?php
// +-----------------+--------------+------+-----+---------+----------------+
// | Field           | Type         | Null | Key | Default | Extra          |
// +-----------------+--------------+------+-----+---------+----------------+
// | id              | int(11)      | NO   | PRI | NULL    | auto_increment |
// | name            | varchar(50)  | YES  |     |         |                |
// | title           | varchar(50)  | YES  |     |         |                |
// | meta_type       | varchar(50)  | YES  |     |         |                |
// | parent_id       | int(11)      | YES  |     | 0       |                |
// | sort_num        | int(11)      | YES  |     | 0       |                |
// | seo_title       | varchar(255) | YES  |     |         |                |
// | seo_keywords    | varchar(255) | YES  |     |         |                |
// | seo_description | varchar(255) | YES  |     |         |                |
// | template_index  | varchar(100) | YES  |     |         |                |
// | template_list   | varchar(100) | YES  |     |         |                |
// | template_show   | varchar(100) | YES  |     |         |                |
// | is_leaf         | tinyint(1)   | YES  |     | 1       |                |
// | status          | tinyint(1)   | YES  |     | 1       |                |
// | editor_id       | int(11)      | YES  |     | 0       |                |
// | create_time     | int(11)      | YES  |     | 0       |                |
// | update_time     | int(11)      | YES  |     | 0       |                |
// +-----------------+--------------+------+-----+---------+----------------+
namespace app\common\model;
use think\Loader;
use think\Cache;
class Category extends Base{
  protected $auto = ['editor_id'];
  
  protected static function init(){
    Category::event('after_insert', function($data){
      Cache::rm("category_Article");
    });
    Category::event('after_update', function($data){
      Cache::rm("category_Article");
    });
  }

  public function createOrUpdate($data, $id = 0){
    $res = ["status" => false, "msg" => "分类保存失败"];
    $validate = Loader::validate("Category");
    if($validate->check($data)){
      if($id > 0){
        $data["id"] = $id;
      }
      
      if(empty($data["id"])){
        $this->save($data);
      }else{
        $this->isUpdate(true)->save($data);
      }
      $res = ["status" => true, "msg" => "分类保存成功"];
    }else{
      $res["msg"] = $validate->getError();
    }
    return $res;
  }

  /**
   * 查询启用的单条分类记录
   * @Author zhanghong
   * @Date   2017-05-01
   * @param  string     $type Category Type
   * @param  string     $name 分类名
   * @param  integer    $id   分类ID
   * @return array            Category Item
   */
  public function activeFindByName($type, $name, $id = 0){
    $this->where("status", true)->where("type", $type);
    if(empty($name)){
      $this->where("id", $id);
    }else{
      $this->where("name", trim($name));
    }
    $item = $this->find();
    return $item;
  }

  /**
   * 树状结构菜单
   * @Author zhanghong
   * @Date   2017-01-01
   * @param  string     $meta_type 菜单类型
   * @param  integer    $parent_id 根结点ID
   * @param  boolean    $skip_hide 是否忽略隐藏结点
   * @param  integer    $level     结点深度
   * @return array                 Tree
   */
  public function findWithDescendants($meta_type, $parent_id = 0, $skip_hide = true, $level = 0){
    $this->where("parent_id", $parent_id)->where("meta_type", $meta_type);
    if($skip_hide){
      $this->where("status", 1);
    }
    $children = $this->order("sort_num, id")->select();
    if(!empty($children)){
      //如果有子类
      foreach ($children as $key => &$child) {
        $child["deep_level"] = $level;
        $child["children"] = $this->findWithDescendants($meta_type, $child["id"], $skip_hide, $level+1);
      }
    }

    return $children;
  }

  /**
   * 缓存Mate类型的数据
   * @Author zhanghong
   * @Date   2017-04-11
   * @param  string     $meta_type   Meta类型
   * @param  boolean    $only_active 是否只返回显示记录
   * @return array
   */
  public function mateCacheList($meta_type, $only_active = true){
    $key_name = "category_{$meta_type}";
    $list = Cache::get($key_name);
    if(empty($list)){
      $list = $this->explandWithDescendants($meta_type, [], 0, $only_active);
      // 缓存过期时间在config.php文件里设置
      Cache::set($key_name, $list);
    }
    return $list;
  }

  /**
   * 一维数组结构菜单
   * @Author zhanghong
   * @Date   2017-01-01
   * @param  string     $meta_type 菜单类型
   * @param  array      $list      保存菜单的数组
   * @param  integer    $parent_id 根结点ID
   * @param  boolean    $only_active 是否只返回显示记录
   * @param  array      $ancestor_ids 所有祖先结点ID
   * @param  string     $prefix       显示名前辍
   * @return array                    Rule集合
   */
  public function explandWithDescendants($meta_type, $list, $parent_id = 0, $only_active = false, $ancestor_ids = [], $prefix=""){
    $map = [
      "parent_id" => $parent_id,
      "meta_type" => $meta_type,
    ];
    if($only_active){
      $map["status"] = true;
    }
    $children = $this->where($map)->order("sort_num, id")->select();
    if(!empty($children)){
      //如果有子类
      $level = count($ancestor_ids);
      foreach ($children as $key => $child) {
        $child["deep_level"] = $level;
        $child["shown_title"] = $prefix.$child["title"];
        $list[] = $child;
        $sub_ancestor_ids = $ancestor_ids;
        array_push($sub_ancestor_ids, $child["id"]);
        //所有祖先结点和自己的ID列表
        $child["with_ancestor_ids"] = $sub_ancestor_ids;
        if($level == 0){
          //第二级菜单
          $sub_prefix = "┗━";
        }else if($level > 0){
          //第二级以后的菜单
          $sub_prefix = '&nbsp;&nbsp;&nbsp;&nbsp;'.$prefix;
        }
        $list = $this->explandWithDescendants($meta_type, $list, $child["id"], $only_active, $sub_ancestor_ids, $sub_prefix);
      }
    }
    return $list;
  }    
}